/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.liangjun.medicalhistorybefore.service.impl;

import me.liangjun.medicalhistorybefore.domain.ImmuneSystemDiseaseFamilyHistory;
import me.liangjun.medicalhistorybefore.domain.MedicalHistoryBefore;
import me.liangjun.medicalhistorybefore.domain.PastDisease;
import me.liangjun.medicalhistorybefore.domain.PastDiseaseInfo;
import me.liangjun.medicalhistorybefore.repository.ImmuneSystemDiseaseFamilyHistoryRepository;
import me.liangjun.medicalhistorybefore.repository.PastDiseaseInfoRepository;
import me.liangjun.medicalhistorybefore.repository.PastDiseaseRepository;
import me.liangjun.medicalhistorybefore.service.dto.*;
import me.liangjun.medicalhistorybefore.service.mapstruct.ImmuneSystemDiseaseFamilyHistoryMapper;
import me.liangjun.medicalhistorybefore.service.mapstruct.PastDiseaseInfoMapper;
import me.liangjun.medicalhistorybefore.service.mapstruct.PastDiseaseMapper;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import me.liangjun.medicalhistorybefore.repository.MedicalHistoryBeforeRepository;
import me.liangjun.medicalhistorybefore.service.MedicalHistoryBeforeService;
import me.liangjun.medicalhistorybefore.service.mapstruct.MedicalHistoryBeforeMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;

import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;

/**
 * @author wei
 * @website https://el-admin.vip
 * @description 服务实现
 * @date 2021-09-04
 **/
@Service
@RequiredArgsConstructor
public class MedicalHistoryBeforeServiceImpl implements MedicalHistoryBeforeService {

    private final MedicalHistoryBeforeRepository medicalHistoryBeforeRepository;
    private final MedicalHistoryBeforeMapper medicalHistoryBeforeMapper;
    private final ImmuneSystemDiseaseFamilyHistoryMapper immuneSystemDiseaseFamilyHistoryMapper;
    private final PastDiseaseMapper pastDiseaseMapper;
    private final ImmuneSystemDiseaseFamilyHistoryRepository immuneSystemDiseaseFamilyHistoryRepository;
    private final PastDiseaseRepository pastDiseaseRepository;
    private final PastDiseaseInfoMapper pastDiseaseInfoMapper;
    private final PastDiseaseInfoRepository pastDiseaseInfoRepository;

    @Override
    public Map<String, Object> queryAll(MedicalHistoryBeforeQueryCriteria criteria, Pageable pageable) {
        Page<MedicalHistoryBefore> page = medicalHistoryBeforeRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(medicalHistoryBeforeMapper::toDto));
    }

    @Override
    public List<MedicalHistoryBeforeDto> queryAll(MedicalHistoryBeforeQueryCriteria criteria) {
        return medicalHistoryBeforeMapper.toDto(medicalHistoryBeforeRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public MedicalHistoryBeforeDto findById(Long id) {
        MedicalHistoryBefore medicalHistoryBefore = medicalHistoryBeforeRepository.findById(id).orElseGet(MedicalHistoryBefore::new);
        ValidationUtil.isNull(medicalHistoryBefore.getId(), "MedicalHistoryBefore", "id", id);
        List<ImmuneSystemDiseaseFamilyHistory> immuneSystemDiseaseFamilyHistoryList = immuneSystemDiseaseFamilyHistoryRepository.findListByPid(medicalHistoryBefore.getPId());
        List<PastDisease> diseaseList = pastDiseaseRepository.findListByPid(medicalHistoryBefore.getPId());
        List<PastDiseaseDto> pastDiseaseDtos = new ArrayList<>();
        for (PastDisease pastDisease : diseaseList) {
            List<PastDiseaseInfo> pastDiseaseInfoList = pastDiseaseInfoRepository.findByPidAndName(pastDisease.getPId(), pastDisease.getDiseaseName());
            pastDiseaseDtos.add(pastDiseaseMapper.domain2dto(pastDisease, pastDiseaseInfoList));
        }
        if (immuneSystemDiseaseFamilyHistoryList.size() == 0) {
            immuneSystemDiseaseFamilyHistoryList = null;
        }
         if (pastDiseaseDtos.size() == 0) {
             pastDiseaseDtos = null;
        }

        return medicalHistoryBeforeMapper.domain2dto(medicalHistoryBefore, immuneSystemDiseaseFamilyHistoryList, pastDiseaseDtos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MedicalHistoryBeforeDto create(MedicalHistoryBeforeDto resources) {
        List<ImmuneSystemDiseaseFamilyHistoryDto> familyHistoryDtoList = resources.getFamilyHistoryDtoList();
        List<PastDiseaseDto> medicalHistoryDetails = resources.getMedicalHistoryDetails();
        MedicalHistoryBefore medicalHistoryBefore = medicalHistoryBeforeMapper.toEntity(resources);
        MedicalHistoryBefore medicalHistoryBefore1 = medicalHistoryBeforeRepository.findByPid(medicalHistoryBefore.getPId());
        MedicalHistoryBefore historyBefore = null;
        if (medicalHistoryBefore1 != null) {
            medicalHistoryBefore1.copy(medicalHistoryBefore);
            historyBefore = medicalHistoryBeforeRepository.save(medicalHistoryBefore1);
        }else {
            historyBefore = medicalHistoryBeforeRepository.save(medicalHistoryBefore);
        }
        List<ImmuneSystemDiseaseFamilyHistory> immuneSystemDiseaseFamilyHistories = immuneSystemDiseaseFamilyHistoryMapper.toEntity(familyHistoryDtoList);
        MedicalHistoryBeforeDto medicalHistoryBeforeDto = medicalHistoryBeforeMapper.toDto(historyBefore);

        List<ImmuneSystemDiseaseFamilyHistory> saveFamilyHistoryList = new ArrayList<>();
        for (ImmuneSystemDiseaseFamilyHistory immuneSystemDiseaseFamilyHistory : immuneSystemDiseaseFamilyHistories) {
            if (medicalHistoryBeforeDto.getFamilyHistoryDtoListString().contains(String.valueOf(immuneSystemDiseaseFamilyHistory.getName()))) {
                if(immuneSystemDiseaseFamilyHistory.getId()!=null) {
                    ImmuneSystemDiseaseFamilyHistory one = immuneSystemDiseaseFamilyHistoryRepository.findOne(immuneSystemDiseaseFamilyHistory.getId(), immuneSystemDiseaseFamilyHistory.getName());
                    if (one != null) {
                        one.copy(immuneSystemDiseaseFamilyHistory);
                        saveFamilyHistoryList.add(one);
                    }
                }
                saveFamilyHistoryList.add(immuneSystemDiseaseFamilyHistory);
            }
        }

        List<PastDiseaseDto> efficientMedicalHistoryDetails = new ArrayList<>();
        for (PastDiseaseDto medicalHistoryDetail : medicalHistoryDetails) {
            if (medicalHistoryBeforeDto.getMedicalHistoryDetailsString().contains(medicalHistoryDetail.getDiseaseName())) {
                efficientMedicalHistoryDetails.add(medicalHistoryDetail);
            }
        }
        List<PastDiseaseDto> pastDiseaseDtos = new ArrayList<>();
        for (PastDiseaseDto pastDiseaseDto : efficientMedicalHistoryDetails) {
            List<PastDiseaseInfo> pastDiseaseInfos = new ArrayList<>();
            String diseaseName = pastDiseaseDto.getDiseaseName();
            List<String> diagnosisName = pastDiseaseDto.getDiagnosisName();
            List<PastDiseaseInfo> diseaseInfos = pastDiseaseInfoMapper.toEntity(pastDiseaseDto.getPastDiseaseInfoDtos());
            PastDisease pastDisease = pastDiseaseMapper.toEntity(pastDiseaseDto);
            PastDisease one = pastDiseaseRepository.findOne(pastDisease.getPId(), pastDisease.getDiseaseName());
            PastDisease save = null;
            if (one != null) {
                one.copy(pastDisease);
                save = one;
            }else {
                save = pastDiseaseRepository.save(pastDisease);
            }
            PastDiseaseDto diseaseDto = pastDiseaseMapper.toDto(save);
            if (diseaseInfos != null) {
                for (PastDiseaseInfo pastDiseaseInfo : diseaseInfos) {
                    if (diagnosisName.contains(pastDiseaseInfo.getDiagnosisName())) {
                        pastDiseaseInfo.setDiseaseName(diseaseName);
                        pastDiseaseInfo.setPId(resources.getPId());
                        pastDiseaseInfos.add(pastDiseaseInfo);
                    }
                }
                List<PastDiseaseInfo> diseaseInfoList = pastDiseaseInfoRepository.saveAll(pastDiseaseInfos);
                diseaseDto = pastDiseaseMapper.domain2dto(save, diseaseInfoList);
            }
            pastDiseaseDtos.add(diseaseDto);
        }
        List<ImmuneSystemDiseaseFamilyHistory> immuneSystemDiseaseFamilyHistoryList = immuneSystemDiseaseFamilyHistoryRepository.saveAll(saveFamilyHistoryList);
        if (immuneSystemDiseaseFamilyHistoryList.size() == 0) {
            immuneSystemDiseaseFamilyHistoryList = null;
        }
        if (pastDiseaseDtos.size() == 0) {
            pastDiseaseDtos = null;
        }

        MedicalHistoryBeforeDto medicalHistoryBeforeDto1 = medicalHistoryBeforeMapper.domain2dto
                (historyBefore,
                        immuneSystemDiseaseFamilyHistoryList,
                        pastDiseaseDtos);
        return medicalHistoryBeforeDto1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(MedicalHistoryBeforeDto resources) {
        MedicalHistoryBefore medicalHistoryBefore = medicalHistoryBeforeRepository.findById(resources.getId()).orElseGet(MedicalHistoryBefore::new);
        ValidationUtil.isNull(medicalHistoryBefore.getId(), "MedicalHistoryBefore", "id", resources.getId());

        List<PastDiseaseDto> medicalHistoryDetails = resources.getMedicalHistoryDetails();
        List<PastDisease> pastDiseases = pastDiseaseMapper.toEntity(medicalHistoryDetails);
        pastDiseaseRepository.saveAll(pastDiseases);

        List<ImmuneSystemDiseaseFamilyHistoryDto> familyHistoryDtoList = resources.getFamilyHistoryDtoList();
        List<ImmuneSystemDiseaseFamilyHistory> immuneSystemDiseaseFamilyHistories = immuneSystemDiseaseFamilyHistoryMapper.toEntity(familyHistoryDtoList);
        immuneSystemDiseaseFamilyHistoryRepository.saveAll(immuneSystemDiseaseFamilyHistories);

        medicalHistoryBefore.copy(medicalHistoryBeforeMapper.toEntity(resources));
        medicalHistoryBeforeRepository.save(medicalHistoryBefore);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            medicalHistoryBeforeRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<MedicalHistoryBeforeDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (MedicalHistoryBeforeDto medicalHistoryBefore : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("pID", medicalHistoryBefore.getPId());
            map.put("有无既往病史", medicalHistoryBefore.getHaveMedicalHistory());
            map.put("病史详情", medicalHistoryBefore.getMedicalHistoryDetails());
            map.put("有无家族病史", medicalHistoryBefore.getHaveMedicalFamilyHistory());
            map.put("与患者关系", medicalHistoryBefore.getRelationship());
            map.put("系谱图", medicalHistoryBefore.getPedigree());
            map.put("免疫系统疾病家族史有无", medicalHistoryBefore.getHaveImmuneMedicalFamilyHistory());
            map.put("免疫系统疾病家族史_诊断名称", medicalHistoryBefore.getFamilyHistoryDtoList());
            map.put("吸烟史", medicalHistoryBefore.getSmoke());
            map.put("是否戒烟:", medicalHistoryBefore.getQuitSmoking());
            map.put("饮酒史:", medicalHistoryBefore.getDrink());
            map.put("是否戒酒:", medicalHistoryBefore.getQuitDrinking());
            map.put("患者入组情况:", medicalHistoryBefore.getIsRuzu());
            map.put("备注::", medicalHistoryBefore.getRemarks());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public MedicalHistoryBeforeDto findByPid(Long pid) {
        MedicalHistoryBefore medicalHistoryBefore = medicalHistoryBeforeRepository.findByPid(pid);
        List<ImmuneSystemDiseaseFamilyHistory> familyHistoryList = immuneSystemDiseaseFamilyHistoryRepository.findListByPid(pid);
        List<PastDisease> diseaseList = pastDiseaseRepository.findListByPid(pid);
        List<PastDiseaseDto> pastDiseaseDtos = new ArrayList<>();
        for (PastDisease pastDisease : diseaseList) {
            List<PastDiseaseInfo> pastDiseaseInfoList = pastDiseaseInfoRepository.findByPidAndName(pastDisease.getPId(), pastDisease.getDiseaseName());
            pastDiseaseDtos.add(pastDiseaseMapper.domain2dto(pastDisease, pastDiseaseInfoList));
        }

        return medicalHistoryBeforeMapper.domain2dto(medicalHistoryBefore,familyHistoryList,pastDiseaseDtos);
    }
}